package GameEngine.Drawables;

import processing.core.PGraphics;
import processing.core.PImage;
import GameEngine.Animation.Programmed.Animation;
import GameEngine.Animation.Programmed.LoopAnimation;
import GameEngine.helper.PAppletBridge;


public class AnimatedSprite extends Drawable {

	private int NumPhases = 13;
	private PImage sheet;
	private PImage[] phases = new PImage[NumPhases];
	private PImage[] flippedPhases = new PImage[NumPhases];

	private int currentFrame = 0;
	private boolean flipped = false;
	
	private Animation ANI;

	public boolean isFlipped() {
		return flipped;
	}

	public void setFlipped(boolean flipped) {
		this.flipped = flipped;
	}

	public AnimatedSprite(String fname) {
		initializeArrays(13);
		initPhases(fname);
	}

	public AnimatedSprite(PImage sheet) {
		initializeArrays(13);
		initPhases(sheet);
	}

	public AnimatedSprite(String fname, int numPhases, Animation ani) {
		initializeArrays(numPhases);
		initPhases(fname);
		ANI = ani;
	}

	private void initializeArrays(int numPhases) {
		NumPhases = numPhases;
		phases = new PImage[numPhases];
		flippedPhases = new PImage[numPhases];
	}

	public void initPhases(String fname) {
		sheet = PAppletBridge.loadImage(fname);
		cutSheetRegular(70);
	}

	public void initPhases(PImage s) {
		sheet = s;
		cutSheet();
	}
	
	
	private void cutSheetRegular (int w) {
		int format = processing.core.PConstants.ARGB;
		for (int i = 0; i < NumPhases; i++) {
			createPhase(i, i*w, 3, w, 109, format);			
		}
		// save flipped phases
		for (int i = 0; i < NumPhases; i++) {
			flippedPhases[i] = flipImage(phases[i]);
		}
	}

	private void cutSheet() {
		int format = processing.core.PConstants.ARGB;

		// Phase 1, 4,3 -> 32,85
		createPhase(0, 4, 3, 32, 85, format);

		// Phase 2, 55,3 -> 35,88
		createPhase(1, 55, 3, 35, 85, format);

		// Phase 3, 105,3 -> 43,85
		createPhase(2, 105, 3, 43, 85, format);

		// Phase 4, 155,3 -> 51,85
		createPhase(3, 155, 3, 51, 85, format);

		// Phase 5, 207,3 -> 51,85
		createPhase(4, 207, 3, 51, 85, format);

		// Phase 6, 266,3 -> 51,85
		createPhase(5, 266, 3, 51, 85, format);

		// Phase 7, 327,3 -> 61,85
		createPhase(6, 327, 3, 61, 85, format);

		// Phase 8, 392,3 -> 64,85
		createPhase(7, 392, 3, 64, 85, format);

		// Phase 9, 461,3 -> 49,85
		createPhase(8, 462, 3, 49, 85, format);

		// Phase 10, 514,3 -> 54,85
		createPhase(9, 514, 3, 54, 85, format);

		// Phase 11, 575,3 -> 65,85
		createPhase(10, 575, 3, 65, 85, format);

		// Phase 12, 649,3 -> 60,85
		createPhase(11, 649, 3, 60, 85, format);

		// Phase 13, 714,3 -> 46,85
		createPhase(12, 714, 3, 46, 85, format);

		// save flipped phases
		for (int i = 0; i < NumPhases; i++) {
			flippedPhases[i] = flipImage(phases[i]);
		}
	}

	private void createPhase(int idx, int sx, int sy, int w, int h, int format) {
		phases[idx] = PAppletBridge.createImage(w, h, format);
		phases[idx].copy(sheet, sx, sy, w, h, 0, 0, w, h);
	}

	private PImage flipImage(PImage img) {
		PGraphics pg = PAppletBridge.createGraphics(img.width, img.height);

		pg.beginDraw();

		pg.pushMatrix();
		pg.scale(-1.0f, 1.0f);
		pg.image(img, -img.width, 0);
		pg.popMatrix();

		pg.endDraw();

		return pg;
	}


	// Zugriff auf die Phasen

	public PImage getPhase(int frame) {
		if (isFlipped()) {
			return flippedPhases[frame];
		} else {
			return phases[frame];
		}
	}

	// Getter Setter
	public int getCurrentFrame() {
		return currentFrame;
	}

	public void setCurrentFrame(int currentFrame) {
		this.currentFrame = currentFrame;
	}

	// Drawing
	public void draw() {
		currentFrame = (int) ((LoopAnimation)ANI).normalizedCurrentValue();
		
		PAppletBridge.pushMatrix();
		PAppletBridge.translate(getPosx(), getPosy());
		PAppletBridge.image(getPhase(getCurrentFrame()), 0, 0);
		PAppletBridge.popMatrix();
	}

	// Updating

}
